package com.asa.jihe.utils;

import com.asa.hutils.MathHUtils;
import com.asa.hutils.Ni;
import com.asa.jihe.utils.n.LineN;
import com.asa.jihe.utils.n.PointN;

/**
 * N维空间计算
 * @author asa
 *
 */
public class Calculate_Space {
	
	
	
	public static boolean online() {
		
		
		
		
		return false;
	}
	
	
	
	
	
	/**
	 * 把一个n维的点对象转化成一个数组
	 */
	public static double[] pointn2arr(PointN pointn) {
		
		double[] x = new double[pointn.x.length];
		
		for (int i = 0; i < x.length; i++) {
			x[i] = pointn.x[i];
		}
		
		return x;
	}
	
	/**
	 * n维空间中两点的距离
	 * @param x1
	 * @param y1
	 * @param x2
	 * @param y2
	 * @return
	 */
	public static double distance_n(double[] a,double[] b) {
		
		if (a.length<1) {
			throw new RuntimeException("a数组太短了，不能小于1");
		}
		
		if (a.length!=b.length) {
			throw new RuntimeException("数组长度不一致");
		}
		
		double asa = 0;
		
		for (int i = 0; i < b.length; i++) {
			asa += (a[i]-b[i])*(a[i]-b[i]);
		}
		
		asa = Math.sqrt(asa);
		
		return asa;
	}
	
	
	
	
	
	/*求直线的交点，注意平形的情况无解，避免RE*/
//	Point LineInter(LineN l1, LineN l2)
//	{
//	    //求两直线得交点坐标
//	    Point tmp; 
//	    double a1 = l1.a;
//	    double b1 = l1.b;
//	    double c1 = l1.c;
//	    double a2 = l2.a;
//	    double b2 = l2.b;
//	    double c2 = l2.c;
//	    //注意这里b1 = 0 
//	    if(Math.abs(b1) < eps){
//	        tmp.x = -c1 / a1;  
//	        tmp.y = (-c2 - a2 * tmp.x) / b2;
//	    }       
//	    else{
//	        tmp.x = (c1 * b2 - b1 * c2) / (b1 * a2 - b2 * a1);
//	        tmp.y = (-c1 - a1 * tmp.x) / b1;
//	    }
//	    //cout << "交点坐标" << endl; 
//	    //cout << a1 * tmp.x + b1 * tmp.y + c1 << endl;
//	    //cout << a2 * tmp.x + b2 * tmp.y + c2 << endl;
//		return tmp;
//	}
	
	
	
	
	
	/**
	 * 空间向量间的点乘
	 */
	public static double diancheng(PointN a,PointN b) {
//		double asa = a.x*b.x + a.y*b.y;
		double asa = 0;
		for (int i = 0; i < a.x.length; i++) {
			
			double d1 = a.x[i];
			double d2 = b.x[i];
			
			asa += d1*d2;
			
		}
		
		return asa;
	}
	
	
	
	
	
	/**
	 * 空间向量间的叉乘
	 * 他们说叉乘只有三维才有定义，叉乘的计算结构代表垂直于这两个向量的一个向量
	 * 其实这个叉乘类似于中间量，相当它把求体积的n维的公式拆分成两部分，一部分是叉乘（n-1），一部分是点乘（n-1）*1
	 * 
	 */
	public static PointN chacheng(PointN[] a) {
		
//		double[] x1 = a.x;
		
		if (a.length!=a[0].x.length-1) {
			throw new RuntimeException("计算错误，向量组PointN长度不匹配");
		}
		
		
		PointN asa = new PointN();
		asa.x = new double[a[0].x.length];
		
		for (int reject = 0; reject < a[0].x.length; reject++) {
			double[][] a_ = new double[a[0].x.length-1][a[0].x.length-1];

			for (int i = 0; i < a.length; i++) {
				for (int j = 0; j < a[i].x.length; j++) {
					if (j<reject) {
						a_[i][j] = a[i].x[j];
					}else if(j>reject){
						a_[i][j-1] = a[i].x[j];
					}
				}
			}
			double d_shu = Ni.hangleishivalue(a_ );
			if (reject%2==0) {
				asa.x[reject] = d_shu;
			}else {
				asa.x[reject] = -d_shu;

			}
			
		}
		
		
		
		return asa;
	}
	
	
	
	/**
	 * 计算空间中的从坐标原点出发的向量的体积
	 * 
	 * 一个矩阵的行列式就是一个平行多面体的（定向的）体积,这个结论是非常深刻的，务必注意，很多人学了高代都没有搞清楚这个
	 */
	public static double tiji(PointN[] a) {
		
		double[][] a_ = new double[a.length][a.length];
		
		
		for (int i = 0; i < a_.length; i++) {
			a_[i] = a[i].x;
		}
		
//		a_ = MathHUtils.zhuanzhi(a_);
		
		double hangleishivalue = Ni.hangleishivalue(a_ );
//		System.out.println(a_[0][1]+"       "+ a_[1][0]+"      "+ a_[2][2]);
//		System.out.println(a_[0][2]+"       "+ a_[1][1]+"      "+ a_[2][0]);

		return hangleishivalue;
	}
	
	
	
	public static void main(String[] args) {
		
		PointN[] a = new PointN[3];
		a[0] = new PointN();
		a[1] = new PointN();
		a[2] = new PointN();
		
//		a[0].x = new double[]{0,2,3};
//		a[1].x = new double[]{1,-2,0};
//		a[2].x = new double[]{-2,0,5};

		a[0].x = new double[]{0,0,3};
		a[1].x = new double[]{0,1,1};
		a[2].x = new double[]{2,4,5};
		
		double tiji = tiji(a);
		
//		System.out.println(tiji);
		
		
		
		PointN a1 = new PointN();
		a1.x = new double[]{-10,-5,-4};
		
		PointN b1 = new PointN();
		b1.x = new double[]{0,2,3};

		
		double diancheng = diancheng(a1 , b1);
//		System.out.println(diancheng);

		
		
		
		
		PointN[] a2 = new PointN[2];
		a2[0] = a[1] ;
		a2[1] = a[2] ;
		
		PointN chacheng = chacheng(a2);
		
//		for (int i = 0; i < chacheng.x.length; i++) {
//			System.out.println(chacheng.x[i]);
//		}
		
		
		double diancheng2 = diancheng(chacheng, a[0]);
		System.out.println(diancheng2);
		
	}
	
	
	
	
	
	
	
	/**
	 * 把一个n维数组，转化成一个点对象
	 * @param x
	 * @return
	 */
	public static PointN arr2pointn(double[] x) {
		
		PointN pointn = new PointN(); 
		
		pointn.x = new double[x.length];
		
		for (int i = 0; i < x.length; i++) {
			pointn.x[i] = x[i];
		}
		
		
		return pointn;
	}
	
	
	
	
	

}
